using Microsoft.Extensions.Logging;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Web;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Services.Notification
{
    /// <summary>
    /// 阿里云短信服务提供商
    /// 支持阿里云短信服务API
    /// </summary>
    public class AliyunSmsProvider : ISmsProvider, IDisposable
    {
        public string Name => "阿里云短信";

        public bool IsConfigured => !string.IsNullOrEmpty(_settings.AccessKeyId) &&
                                   !string.IsNullOrEmpty(_settings.AccessKeySecret);

        private readonly AliyunSmsSettings _settings;
        private readonly ILogger _logger;
        private readonly HttpClient _httpClient;
        private const string ALIYUN_SMS_ENDPOINT = "https://dysmsapi.aliyuncs.com/";

        public AliyunSmsProvider(AliyunSmsSettings settings, ILogger logger)
        {
            _settings = settings ?? throw new ArgumentNullException(nameof(settings));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _httpClient = new HttpClient
            {
                Timeout = TimeSpan.FromSeconds(30)
            };
        }

        /// <summary>
        /// 发送普通短信
        /// </summary>
    public Task<SmsSendResult> SendAsync(SmsMessage message)
        {
            if (!IsConfigured)
            {
        return Task.FromResult(new SmsSendResult
                {
                    Success = false,
                    ErrorMessage = "阿里云短信提供商未正确配置",
                    SentAt = DateTime.UtcNow,
                    Provider = Name
        });
            }

            // 对于阿里云，普通短信也需要使用模板
            // 这里使用一个通用的文本模板或直接返回错误
            return Task.FromResult(new SmsSendResult
            {
                Success = false,
                ErrorMessage = "阿里云短信服务需要使用模板发送，请使用SendTemplateAsync方法",
                SentAt = DateTime.UtcNow,
                Provider = Name
            });
        }

        /// <summary>
        /// 使用模板发送短信
        /// </summary>
    public async Task<SmsSendResult> SendTemplateAsync(string templateId, Dictionary<string, string> templateParams, string phoneNumber, string? signName = null)
        {
            if (!IsConfigured)
            {
        return new SmsSendResult
                {
                    Success = false,
                    ErrorMessage = "阿里云短信提供商未正确配置",
                    SentAt = DateTime.UtcNow,
                    Provider = Name
        };
            }

            try
            {
                var parameters = BuildSendSmsParameters(templateId, templateParams, phoneNumber, signName);
                
                var startTime = DateTime.UtcNow;
                var response = await SendRequest(parameters);
                var endTime = DateTime.UtcNow;

                if (response.Success)
                {
                    _logger.LogDebug(
                        "阿里云短信发送成功 - 手机号: {Phone}, 模板: {Template}, 耗时: {Duration}ms",
                        MaskPhoneNumber(phoneNumber), templateId, (endTime - startTime).TotalMilliseconds);

                    return new SmsSendResult
                    {
                        Success = true,
                        MessageId = response.BizId,
                        SentAt = endTime,
                        Provider = Name
                    };
                }
                else
                {
                    _logger.LogError(
                        "阿里云短信发送失败 - 手机号: {Phone}, 错误: {Error}",
                        MaskPhoneNumber(phoneNumber), response.ErrorMessage);

                    return new SmsSendResult
                    {
                        Success = false,
                        ErrorMessage = response.ErrorMessage,
                        SentAt = DateTime.UtcNow,
                        Provider = Name
                    };
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "阿里云短信发送异常 - 手机号: {Phone}", MaskPhoneNumber(phoneNumber));
                
                return new SmsSendResult
                {
                    Success = false,
                    ErrorMessage = ex.Message,
                    SentAt = DateTime.UtcNow,
                    Provider = Name
                };
            }
        }

        /// <summary>
        /// 测试连接
        /// </summary>
        public async Task<bool> TestConnectionAsync()
        {
            if (!IsConfigured)
            {
                _logger.LogWarning("阿里云短信提供商未配置，跳过连接测试");
                return false;
            }

            try
            {
                // 使用查询短信发送状态的API来测试连接
                var parameters = new Dictionary<string, string>
                {
                    ["Action"] = "QuerySendDetails",
                    ["Version"] = "2017-05-25",
                    ["AccessKeyId"] = _settings.AccessKeyId,
                    ["SignatureMethod"] = "HMAC-SHA1",
                    ["Timestamp"] = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"),
                    ["SignatureVersion"] = "1.0",
                    ["SignatureNonce"] = Guid.NewGuid().ToString(),
                    ["Format"] = "JSON",
                    ["RegionId"] = _settings.Region,
                    ["PhoneNumber"] = "13800138000", // 测试用号码
                    ["SendDate"] = DateTime.UtcNow.ToString("yyyyMMdd"),
                    ["PageSize"] = "1",
                    ["CurrentPage"] = "1"
                };

                var response = await SendRequest(parameters);
                
                if (response.Success || response.ErrorMessage?.Contains("InvalidPhoneNumber") == true)
                {
                    // 如果成功或者是手机号码错误（说明API可访问），都认为连接正常
                    _logger.LogInformation("阿里云短信服务连接测试成功");
                    return true;
                }
                else
                {
                    _logger.LogError("阿里云短信服务连接测试失败 - 错误: {Error}", response.ErrorMessage);
                    return false;
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "阿里云短信服务连接测试异常");
                return false;
            }
        }

        /// <summary>
        /// 查询发送状态
        /// </summary>
    public Task<SmsSendResult> QuerySendStatusAsync(string messageId)
        {
            if (!IsConfigured)
            {
        return Task.FromResult(new SmsSendResult
                {
                    Success = false,
                    ErrorMessage = "阿里云短信提供商未正确配置",
                    SentAt = DateTime.UtcNow,
                    Provider = Name
        });
            }

            try
            {
                // 阿里云需要手机号和发送日期来查询，这里无法直接通过messageId查询
                // 需要额外的信息，暂时返回未实现
                return Task.FromResult(new SmsSendResult
                {
                    Success = false,
                    ErrorMessage = "阿里云短信状态查询需要额外参数（手机号、发送日期），当前不支持仅通过MessageId查询",
                    SentAt = DateTime.UtcNow,
                    Provider = Name
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询阿里云短信发送状态异常 - 消息ID: {MessageId}", messageId);
                
                return Task.FromResult(new SmsSendResult
                {
                    Success = false,
                    ErrorMessage = ex.Message,
                    SentAt = DateTime.UtcNow,
                    Provider = Name
                });
            }
        }

        /// <summary>
        /// 构建发送短信的请求参数
        /// </summary>
        private Dictionary<string, string> BuildSendSmsParameters(string templateId, Dictionary<string, string> templateParams, string phoneNumber, string? signName = null)
        {
            var parameters = new Dictionary<string, string>
            {
                ["Action"] = "SendSms",
                ["Version"] = "2017-05-25",
                ["AccessKeyId"] = _settings.AccessKeyId,
                ["SignatureMethod"] = "HMAC-SHA1",
                ["Timestamp"] = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"),
                ["SignatureVersion"] = "1.0",
                ["SignatureNonce"] = Guid.NewGuid().ToString(),
                ["Format"] = "JSON",
                ["RegionId"] = _settings.Region,
                ["PhoneNumbers"] = phoneNumber,
                ["SignName"] = !string.IsNullOrEmpty(signName) ? signName : _settings.SignName,
                ["TemplateCode"] = templateId
            };

            // 添加模板参数
            if (templateParams != null && templateParams.Count > 0)
            {
                parameters["TemplateParam"] = JsonSerializer.Serialize(templateParams);
            }

            return parameters;
        }

        /// <summary>
        /// 发送请求
        /// </summary>
        private async Task<AliyunSmsResponse> SendRequest(Dictionary<string, string> parameters)
        {
            try
            {
                // 计算签名
                var signature = CalculateSignature("GET", parameters);
                parameters["Signature"] = signature;

                // 构建GET请求URL
                var queryString = string.Join("&", parameters.Select(p => $"{p.Key}={HttpUtility.UrlEncode(p.Value)}"));
                var requestUrl = ALIYUN_SMS_ENDPOINT + "?" + queryString;

                var response = await _httpClient.GetAsync(requestUrl);
                var responseContent = await response.Content.ReadAsStringAsync();

                if (response.IsSuccessStatusCode)
                {
                    var jsonDoc = JsonDocument.Parse(responseContent);
                    
                    if (jsonDoc.RootElement.TryGetProperty("Code", out var code))
                    {
                        if (code.GetString() == "OK")
                        {
                            var bizId = jsonDoc.RootElement.TryGetProperty("BizId", out var bizIdElement)
                                ? bizIdElement.GetString()
                                : Guid.NewGuid().ToString();
                                
                            return new AliyunSmsResponse
                            {
                                Success = true,
                                BizId = bizId
                            };
                        }
                        else
                        {
                            var message = jsonDoc.RootElement.TryGetProperty("Message", out var messageElement)
                                ? messageElement.GetString()
                                : "未知错误";
                                
                            return new AliyunSmsResponse
                            {
                                Success = false,
                                ErrorMessage = $"阿里云错误 ({code.GetString()}): {message}"
                            };
                        }
                    }
                }

                return new AliyunSmsResponse
                {
                    Success = false,
                    ErrorMessage = $"HTTP错误: {response.StatusCode}, 响应: {responseContent}"
                };
            }
            catch (Exception ex)
            {
                return new AliyunSmsResponse
                {
                    Success = false,
                    ErrorMessage = ex.Message
                };
            }
        }

        /// <summary>
        /// 计算签名
        /// </summary>
        private string CalculateSignature(string httpMethod, Dictionary<string, string> parameters)
        {
            // 移除签名参数
            var signParams = parameters.Where(p => p.Key != "Signature").ToDictionary(p => p.Key, p => p.Value);
            
            // 按key排序
            var sortedParams = signParams.OrderBy(p => p.Key).ToList();
            
            // 构建规范化查询字符串
            var canonicalizedQuery = string.Join("&", sortedParams.Select(p => 
                $"{UrlEncode(p.Key)}={UrlEncode(p.Value)}"));
            
            // 构建待签名字符串
            var stringToSign = $"{httpMethod}&{UrlEncode("/")}&{UrlEncode(canonicalizedQuery)}";
            
            // 计算签名
            var key = _settings.AccessKeySecret + "&";
            using var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(key));
            var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign));
            
            return Convert.ToBase64String(hash);
        }

        /// <summary>
        /// URL编码
        /// </summary>
        private static string UrlEncode(string value)
        {
            return HttpUtility.UrlEncode(value, Encoding.UTF8)
                .Replace("+", "%20")
                .Replace("*", "%2A")
                .Replace("%7E", "~");
        }

        /// <summary>
        /// 手机号码掩码处理
        /// </summary>
        private static string MaskPhoneNumber(string phoneNumber)
        {
            if (string.IsNullOrEmpty(phoneNumber) || phoneNumber.Length < 7)
                return phoneNumber;

            var start = phoneNumber.Substring(0, 3);
            var end = phoneNumber.Substring(phoneNumber.Length - 4);
            var mask = new string('*', phoneNumber.Length - 7);
            
            return start + mask + end;
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            _httpClient?.Dispose();
        }
    }

    /// <summary>
    /// 阿里云短信响应模型
    /// </summary>
    internal class AliyunSmsResponse
    {
        public bool Success { get; set; }
        public string? BizId { get; set; }
        public string? ErrorMessage { get; set; }
    }
}
